package com.xiaodou.mjf.web.xface.user.controller;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.xiaodou.mjf.application.basic.service.SmsService;
import com.xiaodou.mjf.application.core.service.AccountService;
import com.xiaodou.mjf.application.core.service.BankCardService;
import com.xiaodou.mjf.application.user.manager.MemberManager;
import com.xiaodou.mjf.application.user.manager.result.RegisterResult;
import com.xiaodou.mjf.application.user.service.MemberSecurityService;
import com.xiaodou.mjf.application.user.service.MemberService;
import com.xiaodou.mjf.application.user.utils.MemberUtils;
import com.xiaodou.mjf.entity.basic.Sms;
import com.xiaodou.mjf.entity.core.Account;
import com.xiaodou.mjf.entity.core.BankCard;
import com.xiaodou.mjf.entity.user.Member;
import com.xiaodou.mjf.entity.user.MemberSecurity;
import com.xiaodou.mjf.infrastructure.common.controller.ApiController;
import com.xiaodou.mjf.infrastructure.common.utils.CodeGenerator;
import com.xiaodou.mjf.infrastructure.common.utils.Encrypt;
import com.xiaodou.mjf.infrastructure.common.utils.FileUtils;
import com.xiaodou.mjf.infrastructure.common.utils.Global;
import com.xiaodou.mjf.infrastructure.common.utils.StringUtils;
import com.xiaodou.mjf.infrastructure.payeco.tools.Base64;
import com.xiaodou.mjf.web.xface.common.ResultCode;

/**
 * Created by Rocky on 2/26/15.
 */
@RestController
@RequestMapping("v1/user")
public class UserController extends ApiController {

	@Resource
	MemberManager manager;
	@Resource
	MemberSecurityService memberSecurityService;
	@Resource
	MemberService memberService;

	@Resource
	SmsService smsService;

	@Resource
	AccountService accountService;

	@Resource
	BankCardService bankCardService;

	
	public static final Integer STATUS_YES=2;
	
	public static final Integer STATUS_NO=1;
	
	public static final Integer IDENTITY_TYPE_DEFAULT=1;
	
	public static final Integer USER_TYPE=1;
	
	public static final Integer LOGIN_PASSWORD_TYPE=4;
	
	public static final Integer TRADE_PASSWORD_TYPE=5;
	
	public static final Integer RESET_LOGIN_PASSWORD_TYPE=2;
	/**
	 * 用户登陆
	 * 
	 * @param loginCode
	 * @param password
	 * @return
	 */
	@RequestMapping("login")
	public Map<String, Object> login(String phone, String password) {

		if (StringUtils.isBlank(phone) || StringUtils.isBlank(password)) {
			return failure(ResultCode.MISSING_PARAMS);
		}

		try {
			MemberSecurity memberSecurity = memberSecurityService
					.getUserinfo(phone);
			if(memberSecurity==null){
				return failure(ResultCode.USER_NOT_EXIST);
			}
			Member member = memberService.get(memberSecurity.getId());
			if(member==null){
				return failure(ResultCode.USER_NOT_EXIST);
			}
			//更新登陆次数
			member.setLoginCount(member.getLoginCount()+1);
			memberService.save(member);
			if (memberSecurity != null) {
				if (!Encrypt.validatePassword(memberSecurity.getPassword(),
						password)) {
					memberSecurity.setRetryCount((memberSecurity.getRetryCount()==null?0:memberSecurity.getRetryCount())+1);
					memberSecurityService.save(memberSecurity);
					return failure(ResultCode.INVALID_PASSWORD);
				}
				return success("uid", memberSecurity.getId());
			}
		} catch (Exception e) {
			logger.error(e.toString());
		}

		return failure(ResultCode.INVALID_LOGIN);

	}

	/**
	 * 用户注册
	 * 
	 * @param phone
	 * @param code
	 * @param password
	 * @return
	 */
	@RequestMapping("register")
	public Map<String, Object> register(String phone, String code,
			String password) {
		if (StringUtils.isBlank(phone) || StringUtils.isBlank(code)
				|| StringUtils.isBlank(password)) {
			return failure(ResultCode.MISSING_PARAMS);
		}
		// 短信码验证 注册类型type为1
		if (!MemberUtils.verifyCode(phone, code, Sms.TYPE_REGISTER)) {
			return failure(ResultCode.INVALID_VETIFY_CODE);
		}
		// 只返回一条记录 phone唯一
		MemberSecurity memberSecurity = memberSecurityService.getMember(phone);
		if (memberSecurity != null) {
			return failure(ResultCode.INVALID_REGISTER);
		}
		try {
			RegisterResult result = manager.register(phone, password);
			if (!result.isSuccess())
				return failure(ResultCode.REGIST_ERROR);
			return success("uid", result.getUid());
		} catch (Exception e) {
			logger.error(e.toString());
			return failure(ResultCode.REGIST_ERROR);
		}
	}
	

	/**
	 * 设置交易密码
	 * 
	 * @param phone
	 * @param type
	 * @param password
	 * @return
	 */
	@RequestMapping(value = "trade_password", method = RequestMethod.POST)
	public Map<String, Object> trade(String phone, String password,
			@RequestHeader(required = false) String uid) {
		if (StringUtils.isBlank(phone) || StringUtils.isBlank(password)
				|| StringUtils.isBlank(uid)) {
			return failure(ResultCode.MISSING_PARAMS);
		}

		// 交易密码更新
		MemberSecurity memberSecurity = memberSecurityService.get(uid);
		if (memberSecurity != null) {
			memberSecurity.setMobile(phone);
			memberSecurity.setTradePassword(Encrypt.entryptPassword(password));
		} else {
			return failure(ResultCode.USER_SECURITY_NOT_EXIST);
		}
		try {
			memberSecurityService.save(memberSecurity);
		} catch (Exception e) {
			logger.error(e.toString());
			return failure(ResultCode.TRADEPASSWORD_UPDATE_ERROR);
		}
		return success();

	}

    @RequestMapping(value = "validate_trade_password",method = RequestMethod.GET)
    public Map<String,Object> validateTradePassword(@RequestHeader(required = false) String uid,@RequestParam(value = "trade_password",required = false)String tradePassword){

        if (StringUtils.isBlank(uid)) {
            return failure(ResultCode.MISSING_UID_PARAM);
        }
        if (StringUtils.isBlank(tradePassword)) {
            return failure(ResultCode.MISSING_PARAMS);
        }

        MemberSecurity memberSecurity = memberSecurityService.get(uid);
        if(memberSecurity != null && Encrypt.validatePassword(memberSecurity.getTradePassword(),tradePassword)){
            return success();
        }

        return failure(ResultCode.TRADE_PASSWORD_NOT_MATCH);

    }

	/**
	 * 检查交易密码是否存在
	 * 
	 * @param uid
	 * @return
	 */
	@RequestMapping(value = "trade_password", method = RequestMethod.GET)
	public Map<String, Object> judge(@RequestHeader(required = false) String uid) {
		if (StringUtils.isBlank(uid)) {
			return failure(ResultCode.MISSING_PARAMS);
		}
		//
		MemberSecurity memberSecurity = memberSecurityService.get(uid);
		if (memberSecurity != null && memberSecurity.getTradePassword() != null) {
			return success();
		}

		return failure(ResultCode.TRADEPASSWORD_NOT_EXIST);

	}

	/**
	 * 状态查询
	 * 
	 * @param uid
	 * @return
	 */
	@RequestMapping(value = "status_info", method = RequestMethod.GET)
	public Map<String, Object> getStatus(
			@RequestHeader(required = false) String uid) {
		Map<String,Object> result = success();
		if (StringUtils.isBlank(uid)) {
			return failure(ResultCode.MISSING_PARAMS);
		}
		// 是否设置交易密码
		MemberSecurity memberSecurity = memberSecurityService.get(uid);
		if (memberSecurity != null && memberSecurity.getTradePassword() != null) {
			result.put("transaction_password_setting_flag", STATUS_YES);
		} else {
			result.put("transaction_password_setting_flag", STATUS_NO);
		}
		// 是否已经认证
		Member member = memberService.get(uid);
		if (member != null && member.getAuthType()!=null && member.getAuthType().intValue() == Member.AUTHED.intValue()) {
			result.put("authenticated_flag", STATUS_YES);
		} else if (member != null && member.getAuthType()!=null && member.getAuthType().intValue() == Member.REGISTERED_AND_WAIT_AUTHED.intValue()) {
			result.put("authenticated_flag", Member.REGISTERED_AND_WAIT_AUTHED);
		}else{
			result.put("authenticated_flag", STATUS_NO);
		}
		// 是否添加过银行卡
		BankCard entity = new BankCard();
		entity.setMemberId(uid);
		entity.setStatus(BankCard.NORMAL);
		List<BankCard> bankCard = bankCardService.list(entity);
		if (bankCard != null && bankCard.size() > 0) {
			result.put("add_bank_card_flag", STATUS_YES);
		} else {
			result.put("add_bank_card_flag", STATUS_NO);
		}
		return result;

	}

	/**
	 * 重置密码
	 * 
	 * @param phone
	 * @param code
	 * @param type
	 *            4：:登录密码 5：交易密码
	 * @param password
	 * @return
	 */
	@RequestMapping("reset_password")
	public Map<String, Object> reset(String phone, String code, Integer type,
			String password) {
		// 验证码验证
		if (StringUtils.isBlank(phone) || StringUtils.isBlank(code)
				|| StringUtils.isBlank(password) || type == null) {
			return failure(ResultCode.MISSING_PARAMS);
		}
		//
		if (MemberUtils.verifyCode(phone, code, type)) {
			// 密码更新
			MemberSecurity memberSecurity = memberSecurityService
					.getMember(phone);
			if (memberSecurity != null) {
				//区分交易密码和登陆密码
				if(LOGIN_PASSWORD_TYPE.equals(type)){
					if(Encrypt.validatePassword(memberSecurity.getPassword(),
							password)){
						return failure(ResultCode.DUPLICATE_PASSWORD);
					}else {
						memberSecurity.setPassword(Encrypt.entryptPassword(password));
					}					
				} else if(TRADE_PASSWORD_TYPE.equals(type)){
					if(Encrypt.validatePassword(memberSecurity.getTradePassword(),
							password)){
						return failure(ResultCode.DUPLICATE_PASSWORD);
					}else {
						memberSecurity.setTradePassword(Encrypt.entryptPassword(password));
					}
				}else if(RESET_LOGIN_PASSWORD_TYPE.equals(type)){					
						memberSecurity.setPassword(Encrypt.entryptPassword(password));
				}
				
			} else {
				return failure(ResultCode.USER_SECURITY_NOT_EXIST);
			}

			try {
				memberSecurityService.save(memberSecurity);
				return success();
			} catch (Exception e) {
				logger.error(e.toString());
				return failure(ResultCode.PASSWORD_UPDATE_ERROR);
			}
		}

		return failure(ResultCode.INVALID_VETIFY_CODE);

	}

	/**
	 * @param uid
	 *            客户编号
	 * @param name
	 *            姓名
	 * @param identity_number
	 *            身份证号 身份认证
	 * */
	@RequestMapping("my/identity_auth")
	public Map<String, Object> identityAuth(
			@RequestHeader(required = false) String uid,
			String name,
			@RequestParam(value = "identity_number", required = false) String identityNumber) {

		if (StringUtils.isBlank(uid)) {
			return failure(ResultCode.MISSING_UID_PARAM);
		}

		if (StringUtils.isBlank(name) || StringUtils.isBlank(identityNumber)) {
			return failure(ResultCode.MISSING_PARAMS);
		}
		// 返回用户信息
		Member member = memberService.get(uid);
		Account account = accountService.getInfoBymemberId(member.getId());
		if (member == null || account == null) {
			return failure(ResultCode.USER_RECORD_NOT_EXIST);
		}
		// 姓名
		try {
			member.setRealName(URLDecoder.decode(name, "UTF-8"));
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		// 身份证号
		member.setIdentityNumber(identityNumber);
		// 证件类型 :默认为1
		member.setIdentityType(IDENTITY_TYPE_DEFAULT);
		//客户类型：默认为1(个人) 2.企业 3，合作机构 4，其他
		member.setType(USER_TYPE);
		// 已登记 未认证 3
		member.setAuthType(Member.REGISTERED_AND_WAIT_AUTHED);
		account.setTitle(member.getRealName());

		try {
//			accountService.save(account);
//			memberService.save(member);
			manager.identityAuth(account, member);
		} catch (Exception e) {
			logger.error(e.toString());
			return failure(ResultCode.IDENTITY_AUTH_ERROR);
		}
		return success();
	}

	/**
	 * 我的账户信息查询
	 * */
	@RequestMapping("my/profile")
	public Map<String, Object> profile(
			@RequestHeader(required = false) String uid) {
		if (StringUtils.isBlank(uid)) {
			return failure(ResultCode.MISSING_UID_PARAM);
		}
		Map<String,Object> result = success();
		// 返回用户信息
		Member member = memberService.get(uid);
		MemberSecurity memberSecurity = memberSecurityService.get(uid);
		Account account = accountService.getInfoBymemberId(uid);
		BankCard entity = new BankCard();
		entity.setMemberId(uid);
		List<BankCard> bankCards = bankCardService.list(entity);
		if (member == null || memberSecurity == null) {
			return failure(ResultCode.USER_RECORD_NOT_EXIST);
		}
		// 用户头像Url header
		if (member.getHeader() == null) {
			result.put("header", "");
		} else {
			result.put("header", Global.getImgPath() + member.getHeader());
		}
		
		// 用户姓名 name
		result.put("name", member.getRealName());
		// 实名认证标识 is_authenticated
		result.put("is_authenticated", member.getAuthType());
		// 身份证号 identity_numer
		result.put("identity_number", member.getIdentityNumber());
		// 手机号 phone_number
		result.put("phone_number", memberSecurity.getMobile());
		//用户的账面余额 book_balance
		if(account!=null){
			result.put("book_balance", new BigDecimal(account.getBookBalance()).toPlainString());
		}else{
			result.put("book_balance", 0);
		}
		
		//银行卡个数 card_amount
		if(bankCards!=null){
			result.put("card_amount", bankCards.size());	
		}else{
			result.put("card_amount", 0);
		}
		
		return result;
	}

	@RequestMapping("my/balance")
	public Map<String, Object> balance(
			@RequestHeader(required = false) String uid) {
		if (StringUtils.isBlank(uid)) {
			return failure(ResultCode.MISSING_UID_PARAM);
		}
		Account account = accountService.getInfoBymemberId(uid);
		Map<String,Object> result = success();
		if (account != null) {
			// book_balance=balance+voucher_balance 账面余额=可用余额+代金券			 
			result.put("balance", new BigDecimal(account.getAvaliableBalance()).toPlainString());
			result.put("book_balance", new BigDecimal(account.getBookBalance()).toPlainString());
			result.put("voucher_balance", new BigDecimal(account.getVoucherBalance()).toPlainString());

		} else {
			result.put("balance", 0D);
			result.put("book_balance", 0D);
			result.put("voucher_balance", 0D);
		}
		return result;
	}

	/**
	 * 修改绑定手机号
	 */
	@RequestMapping(value = "mobile", method = RequestMethod.POST)
	public Map<String, Object> mobile(
			@RequestHeader(required = false) String uid,
			@RequestParam(value = "phone_number", required = false) String phone,
			@RequestParam(value = "verify_code", required = false) String verifyCode,
			String type) {

		if (StringUtils.isBlank(uid) || StringUtils.isBlank(phone)
				|| StringUtils.isBlank(verifyCode)) {
			return failure(ResultCode.MISSING_UID_PARAM);
		}
		Map<String,Object> result = success();
		// 判断验证码是否正确 修改绑定手机为3
		if (MemberUtils.verifyCode(phone, verifyCode,
				Sms.TYPE_RESET_MOBILE_ORIGIN)) {
			if ("2".equals(type)) {
				MemberSecurity memberSecurity = memberSecurityService
						.getMember(phone);
				if (memberSecurity != null) {
					return failure(ResultCode.PHONE_ALREADY_EXIST);
				}

				memberSecurity = memberSecurityService.get(uid);
				if (memberSecurity == null) {
					return failure(ResultCode.USER_SECURITY_NOT_EXIST);
				}
				// 更新member_security表中的手机号
				memberSecurity.setMobile(phone);
				try {
					memberSecurityService.save(memberSecurity);
				} catch (Exception e) {
					logger.error(e.toString());
					return failure(ResultCode.UPDATE_MOBILE_ERROR);
				}
			}
			return result;
		} else {
			return failure(ResultCode.INVALID_VETIFY_CODE);
		}

	}

	/**
	 * 修改图像
	 * 
	 * @throws IOException
	 * */
	@RequestMapping(value = "my/header", method = RequestMethod.POST)
	public Map<String, Object> header(
			@RequestHeader(required = false) String uid,
			@RequestParam(required = false) String data) throws IOException {
        if (StringUtils.isBlank(uid)) {
            return failure(ResultCode.MISSING_UID_PARAM);
        }

        try {

            byte[] dataTmp = Base64.decode(data);
            ByteArrayInputStream is = new ByteArrayInputStream(dataTmp);
            String path = FileUtils.getPath(Member.IMAGE_PATH, uid);
            String fileName = CodeGenerator.UUID() + ".png";
            FileUtils.upload(Global.getFtpHost(), Global.getFtpUser(), Global.getFtpPassword(), Global.getFtpPort(), is, path, fileName);

            Map<String,Object> result = success();
            // 返回用户信息
            Member member = memberService.get(uid);
            // 需更新图片数据
            member.setHeader(path + "/" + fileName);
            //返回用户头像Url
			result.put("header", Global.getImgPath() + member.getHeader());
            // 需更新图片数据
            memberService.save(member);

            return result;
        } catch (Exception e) {
        	logger.error(e.toString());
            return failure(ResultCode.UPDATE_HEADER_ERROR);
        }
        
	}

}
